package model;

import database.Database;
import inventory.DiscoverItem;
import inventory.InventoryItem;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import session.Session;
import user.User;

/**
 * UserPage class extends the base model class in order to implement the user
 * dashboard page model for the user page view of the Lithub website. The
 * userpage is responisble for handling all user dashboard information, such as
 * registered books and friend information.
 *
 * @author Reynaldo Gonzales.
 * @version 1.0
 *
 */
public class UserPage extends Model {

    private HttpServletRequest request;
    public User user;
    public Map<InventoryItem, ArrayList<User>> library;
    public Boolean requiresRedirect;

    /**
     * UserPage() is the reciever of a user page page request from a user on the
     * lithub website to be processed.
     *
     * @param HttpServletRequest request which holds the session information
     * of the requesting user.
     *
     */
    public UserPage(HttpServletRequest req) {
        request = req;
        requiresRedirect = false;
    }

    /**
     * invoke() is a validity check type invokation method, which is used when a
     * user wants to perform an action in their user dashboard page. The class
     * is responsible for preparing information for the view to display, such as
     * book information or trading actions.
     *
     * @param a String which needs to correspond to the various valid actions of
     * the user dashboard page.
     *
     */
    @Override
    public void invoke(String action) {
        if (action.equals("GetContentHTML")) {
            prepareContent();
        } else if (action.equals("LendItem")) {
            lendItem();
        } else if (action.equals("AddBook")) {
            addBook();
        } else if (action.equals("ReturnItem")) {
            returnItem();
        } else if(action.equals("GetDiscoverContent")) {
            prepareDiscoverContent();
        }

        prepareUserPage();
    }

    /**
     * returnItem() implements the returning of an item functionality found in
     * user book trading - the item's status code is changed and the item is
     * re-added to the original owner's inventory.
     *
     */
    private void returnItem() {
        Database d = Database.getDatabase();
        String itemTitle = URLDecoder.decode(request.getParameter("bookTitle"));
        InventoryItem i = d.getInventoryItemByTitle(itemTitle);
        String usernameOfOwner = request.getParameter("usernameOfOwner");
        User owner = d.getUserByUsername(usernameOfOwner);
        Session s = new Session(request);
        user = s.getUserObjectFromSession();

        if (user != null && owner != null && i != null) {
            d.returnItem(i, owner);
        }

        requiresRedirect = true;
    }

    /**
     * addBook() implements the additions of books to a user's inventory list
     * space in the Lithub database.
     *
     */
    private void addBook() {
        requiresRedirect = true;
        String ISBN = request.getParameter("ISBN").toString();
        Database d = Database.getDatabase();
        try {
            InventoryItem i = d.getIventoryItemByISBN(ISBN);
            i = d.insertInventoryItemIntoDatabase(i);

            Session s = new Session(request);
            user = s.getUserObjectFromSession();

            d.AddInventoryItemToUser(i, user);

        } catch (Exception ex) {
            Logger.getLogger(UserPage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void prepareContent() {
        // TODO: prepare only NECESSARY data >:)
    }

    /**
     * lendItem() implements the lending of an item functionality found in user
     * book trading - the item's status code is changed and the item is added to
     * the lend-ee's inventory space.
     *
     */
    private void lendItem() {
        Database d = Database.getDatabase();
        String itemTitle = URLDecoder.decode(request.getParameter("bookTitle"));
        InventoryItem i = d.getInventoryItemByTitle(itemTitle);
        String usernameOfReceiver = request.getParameter("usernameOfReceiver");
        User receiver = d.getUserByUsername(usernameOfReceiver);
        Session s = new Session(request);
        user = s.getUserObjectFromSession();

        if (user != null && receiver != null && i != null) {
            d.lendItem(i, user, receiver);
        }

        requiresRedirect = true;
    }

    /**
     * prepareUserPage() populates the user account information and dashboard
     * with relevant user information when the dashboard view is loaded and
     * shown to the user. The user's friend's list and inventory items are
     * loaded based on the current user's session.
     *
     */
    private void prepareUserPage() {
        // 1) Get the user object from the Session Associative array
        // 2) Populate the user object with the inventory
        Session s = new Session(request);
        user = s.getUserObjectFromSession();

        Database d = Database.getDatabase();
        d.populateUserInventory(user);
        d.populateUserFriendList(user);
    }

    private void prepareDiscoverContent() {
        Database d = Database.getDatabase();
        library = d.getLibrary();
    }
}